/**   
 * @Title: MenuAction.java 
 * @Package com.foreveross.smsh.models.menu.web 
 * @Description: TODO 
 * @author lixiaodong lixiaodong@foreveross.com  
 * @date 2016年3月7日 下午4:30:42 
 * @version V1.0   
 */
package com.foreveross.smsh.models.role.web;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.foreveross.smsh.common.JsonUtil;
import com.foreveross.smsh.common.UUIDGenerator;
import com.foreveross.smsh.core.pojo.TreeNode;
import com.foreveross.smsh.core.web.ModelAction;
import com.foreveross.smsh.models.menu.pojo.Menu;
import com.foreveross.smsh.models.menu.service.MenuService;
import com.foreveross.smsh.models.role.pojo.Role;
import com.foreveross.smsh.models.role.service.RoleService;

/**
 * @ClassName: MenuAction
 * @Description: TODO
 * @author A18ccms a18ccms_gmail_com
 * @date 2016年3月7日 下午4:30:42
 * 
 */
@Controller
@RequestMapping("/role")
public class RoleAction extends ModelAction<Role> {
	private static final Logger logger = LogManager.getLogger(RoleAction.class);
	@Autowired
	private RoleService roleService;
	@Autowired
	private MenuService menuService;

	@RequestMapping(method = RequestMethod.GET)
	public String list() {
		return "models/role/role-list";
	}

	@RequestMapping(value = "/query", method = RequestMethod.POST)
	@ResponseBody
	public void query() {
		roleService.find(getPaginator());
		this.printJson(getPaginator());
	}

	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String add() {
		return "models/role/role-update";
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@ResponseBody
	public void doAdd(Role role) {
		roleService.add(role);
		this.printJson("true");
	}

	@RequestMapping(value = "/update", method = RequestMethod.GET)
	public String update(@ModelAttribute Role role, Model model) {
		model.addAttribute("role", role);
		return "models/role/role-update";
	}

	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@ResponseBody
	public void doUpdate(@ModelAttribute Role role) {
		roleService.update(role);
		this.printJson("true");
	}

	@RequestMapping(value = "/remove", method = RequestMethod.POST)
	@ResponseBody
	public void remove(String id) {
		roleService.delete(id);
		this.printJson("true");
	}

	@RequestMapping(value = "/assign", method = RequestMethod.GET)
	public String assign(String roleId, Model model) {
		List<Menu> menuRoots = getRootMenu();
		List<TreeNode> treeNodeRoots = new ArrayList<TreeNode>();
		for (Menu menu : menuRoots) {
			List<Menu> menus = getChildrenNodes(menu.getId());
			TreeNode treeNode = convert(menu,roleId);
			treeMenuList(treeNode, menus,roleId);
			treeNodeRoots.add(treeNode);
		}
		model.addAttribute("roleId", roleId);
		model.addAttribute("menujson", JsonUtil.toJson(treeNodeRoots));
		return "models/role/assign-menu";
	}

	@RequestMapping(value = "/assign", method = RequestMethod.POST)
	@ResponseBody
	public void doAssign( @RequestParam(value="menuIds[]",required=false)String[] menuIds,String roleId) {
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("roleId", roleId);
		roleService.executeSQLUpdate("delete from tbl_role_menu  where role_id=:roleId", params);
		if(StringUtils.isNotBlank(roleId)&&menuIds!=null){
			for (String menuId : menuIds) {
				params.put("id", UUIDGenerator.getUUIDoffSpace());
				params.put("menuId", menuId);
				roleService.executeSQLUpdate("insert into tbl_role_menu(id,role_id,menu_id) values(:id,:roleId,:menuId)", params);
			}
		}
		this.printJson("true");
	}
	
	@ModelAttribute
	public void getUser(Role role, Model model) {
		if (StringUtils.isNotBlank(role.getId())) {
			role = roleService.get(role.getId());
			model.addAttribute("role", role);
		} else {
			model.addAttribute("role", role);
		}
	}

	/**
	 * 
	 * @Title: getRootOrgan 
	 * @Description: 获取根组织机构 
	 * @return
	 * List<TreeNode> @throws
	 */
	public List<Menu> getRootMenu() {
		return menuService.get("parentId", null);
	}

	/**
	 * @Title: treeMenuList 
	 * @Description: 组装树对象 
	 * @param parentNode 
	 * @param organs 
	 * @return void 
	 * @throws
	 */
	public void treeMenuList(TreeNode parentNode, List<Menu> menus,String roleId) {
		for (Menu menu : menus) {
			TreeNode treeNode = convert(menu,roleId);
			if (parentNode.getId().equals(menu.getParentId())) {
				treeMenuList(treeNode, menus,roleId);
				parentNode.getChildren().add(treeNode);
			}
		}
	}

	/**
	 * 
	 * @Title: getChildrenNodes @Description: 查询根部门下所有组织机构 @param
	 * parentid @param @return List<Organ> @throws
	 */
	private List<Menu> getChildrenNodes(String parentId) {
		return menuService.get("parentId", parentId);
	}

	/**
	 * 将organ对象转换为treenode对象
	 * 
	 * @param organ
	 * @return
	 */
	private TreeNode convert(Menu menu,String roleId) {
		TreeNode node = new TreeNode();
		node.setId(menu.getId());
		node.setText(menu.getName());
		if (menu.getType() == 0) {
			node.setState(TreeNode.STATE_CLOSED);
		} else {
			node.setState(TreeNode.STATE_OPEN);
		}
		Map<String, Object> params =new HashMap<String, Object>();
		params.put("menuId", node.getId());
		params.put("roleId", roleId);
		List<BigInteger> list =roleService.executeSQLQuery("select count(id) from tbl_role_menu rm where rm.role_id =:roleId and rm.menu_id=:menuId", params);
		if(menu.getType()==1&&list.get(0).intValue()>0){
			node.setChecked(true);
		}
		node.getAttributes().put("url", menu.getUrl());
		node.getAttributes().put("parentId", menu.getParentId());
		node.getAttributes().put("type", menu.getType());
		return node;
	}

}
